// 判断是否为对象 ，注意 null 也是对象
const isObject = (val) => val !== null && typeof val === 'object';

/* 
reactive函数
*/
export function reactive(target) {
  // 如果target不是对象, 直接返回它, 不做各应式处理
  if (!isObject(target)) return target;

  const handler = {
    // 劫持读取属性
    get(target, key, receiver) {
      console.log(`获取对象属性${key}值`);
      // 追踪收集依赖
      console.log('收集依赖...')  // track

      // 利用Reflect得到对应的属性值
      const result = Reflect.get(target, key, receiver);
      // 如果属性值也是对象, 创建并返回对应的代理对象, 否则返回原结果值
      return isObject(result) ? reactive(result) : result;
    },

    // 劫持修改和添加属性
    set(target, key, value, receiver) {
      console.log(`设置对象属性${key}值`);

      // 获取旧的属性值
      const oldValue = Reflect.get(target, key, reactive);

      let result = true;
      // 如果新值不等于旧值
      if (oldValue !== value) {
        // 通过Reflect设置属性
        result = Reflect.set(target, key, value, receiver);
        // 如果操作成功, 触发依赖effect执行
        if (result) {
          console.log('触发依赖...') // trigger
        }
      }
      return result;
    },

    // 劫持删除属性
    deleteProperty(target, key) {
      console.log(`删除对象属性${key}值`);

      // 如果存在此属性, 通过Reflect删除属性
      const result = target.hasOwnProperty(key) && Reflect.deleteProperty(target, key);
      // 如果操作成功, 触发依赖effect执行
      if (result) {
        console.log('触发依赖...') // trigger
      }

      return result;
    },
  };
  return new Proxy(target, handler);
}
